# -*- coding: utf-8 -*-

#使用Python Playwright库进行页面导航的生命周期，包括事件状态、等待元素、页面交互和加载超时等。
# 讨论了page.goto(url)方法的工作原理，如等待事件（如'domcontentloaded'、'load'、'networkidle'），
# 以及如何自定义等待策略，特别是在处理异步导航、多重导航和弹出窗口时。
# 在复杂加载场景下使用page.wait_for_function()的高级模式，并指出了如何设置超时时间。

#导航生命周期：导航从更改页面url或页面交互开始，
#导航可能会被取消，如点击未解析的dns地址 或 文件下载
#只有在导航成功提交后，页面才会开始加载文档

from playwright.sync_api import Playwright, sync_playwright, expect

def run(playwright: Playwright) -> None:

    browser = playwright.chromium.launch(headless=False)
    context = browser.new_context()
    page = context.new_page()

    page.goto("https://example.com")
    #1、等待元素：  wait_for()等待元素可见
    page.get_by_text("example domain").wait_for()


    page.goto("https://example.com")
    #2、页面操作：click()、fill 这样的页面操作会自动等待元素
    page.get_by_text("example domain").click()
    page.get_by_label("User Name").fill("John Doe")

    #3、自定义等待：locator.click  结合 wait_for_load_state（）来等待加载事件
    page.locator("button").click()  # Click triggers navigation
    page.wait_for_load_state("networkidle")  # This waits for the "networkidle"

    #4、异步导航:单击一个元素可以在启动导航之前触发异步处理，使用page.expect_navigation()
    with page.expect_navigation():
        page.get_by_text("Navigate after timeout").click()

    #5、多重导航：点击一个元素触发多个导航，使用page.expect_navigation（）显式指向特定的url
    with page.expect_navigation(url="**/login"):
        page.get_by_text("Click me").click()

    #6、加载弹出窗口：显式调用wait_for_load_state（）可确保将弹出窗口加载到所需状态
    with page.expect_popup() as popup_info:
        page.get_by_text("Open popup").click()  # Opens popup
    popup = popup_info.value
    popup.wait_for_load_state("load")

    #7、高级模式：对于具有复杂加载模式的页面page.wait_for_function（）是定义自定义等待条件的强大且可扩展的方法
    page.goto("http://example.com")
    page.wait_for_function("() => window.amILoadedYet()")
    page.screenshot()

    context.close()
    browser.close()

if __name__ == '__main__':

    with sync_playwright() as playwright:
        run(playwright)

